import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getTimeStamp, setTimeStamp } from '@/utils/auth'
import router from '@/router'

// create an axios instance   创建实例
const service = axios.create({
  // 真实请求地址 = 基准路径 + 请求api封装路径
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  // 如果 5000 毫秒都没有响应，就算超时
  timeout: 5000 // request timeout
})

// 时间戳
const timeStamp = () => {
  //  1. 时间间隔(3小时)
  const howTime = 3 * 60 * 60 * 1000
  //  2.获取当前时间戳
  const now = new Date()
  const nowTime = now.getTime()
  //  3.获取存储的时间戳
  const getTime = getTimeStamp()
  //  4.判断有没有超时
  return nowTime - getTime > howTime
}
// 失败请求的回调（暂时没有失败情况，先写一个占位）
// request interceptor
service.interceptors.request.use(
  config => {
    // 凡是有拦截，记得放行
    // 前提条件：有 token
    if (store.getters.token) {
      // 判断是否超时
      // console.log(timeStamp())
      if (timeStamp()) {
        // 清理数据
        store.dispatch('user/logout')
        // 跳转到登录页
        router.push('/login')
        return Promise.reject(new Error('已超时，请重试'))
      }
      setTimeStamp()
      // 统一添加token
      // 这个项目使用的是 Bearer JWT token 标准
      // 固定标准写法为 `Bearer xxx`
      config.headers.Authorization = `Bearer ${store.getters.token}`
    }
    return config
  },
  err => {
    console.log(err)
    return Promise.reject('请求拦截器失败')
  }
)

// 拦截器可以接受两个参数
// 第一个是网络层面成功的回调
// 第二个是网络层面失败的回调
// response interceptor
service.interceptors.response.use(
  // 网络层面的成功
  res => {
    console.log(res)
    const { success, message, data } = res.data
    // console.log(success)
    if (success) {
    // 返回数据
    // 这里是网络成功，数据也成功
    // 一旦拦截了就必须放行不然没数据
    // return res.data.data
      return data
    } else {
      // 数据层面的失败
      // 1.提示错误
      Message.error(message)
      // 2.拒绝当前的 promise 继续执行
      return Promise.reject(new Error(message))
    }
  },
  // 网络层面的失败 如：路径错误，断网，服务器崩溃，其中有一种就是后端认为我们 token 失效
  err => {
    console.dir(err)
    // 我们跟后端约定，如果报错的同时给出代码 10002 就是超时
    // 因为这里的错误很多类型，可能 response 数据不一定存在，所以写更完整的判断保证
    if (err.response && err.response.data && err.response.data.code === 10002) {
      // 清理数据
      store.dispatch('user/logout')
      // 跳转到登录页
      router.push('/login')
    }
    // 1.提示错误
    Message.error(err.message || '系统繁忙，请稍后再试')
    // 2. 拒绝当前的 promise 请求继续执行
    //  默认情况下，请求的 promise 都是走成功的路径
    //  如果想在报错的时候，手动强制停止当前 promise 请求
    return Promise.reject(new Error('系统繁忙，请稍后再试'))
  }
)

export default service
